#include "../src/run.h"
#include <unistd.h>
#include <assert.h>
#include <string>
#include <iostream>
static const std::string LEXICON_DIR = "test";
//s
void test_s(){
  Editor editor("abc");
  Runner runner(&editor,LEXICON_DIR);
  std::string cmd_line = "s\n";
  std::string result = runner.run(cmd_line);
  assert(result==std::string("abc"));
  std::cout << "s test success" << std::endl;
}
//A
void test_A(){
  Editor editor("abc");
  Runner runner(&editor,LEXICON_DIR);
  std::string cmd_line = "A \"ABC\"\n";
  std::string result = runner.run(cmd_line);
  assert(result==std::string("abcABC"));
  std::cout << "A test success" << std::endl;
}
//a
void test_a(){
  Editor editor("abc");
  Runner runner(&editor,LEXICON_DIR);
  std::string cmd_line = "a \"ABC\"\n";
  std::string result = runner.run(cmd_line);
  assert(result==std::string("ABCabc"));
  std::cout << "a test success" << std::endl;
}
//D
void test_D(){
  Editor editor("abc");
  Runner runner(&editor,LEXICON_DIR);
  std::string cmd_line = "D 1\n";
  std::string result = runner.run(cmd_line);
  assert(result==std::string("ab"));
  std::cout << "D test success" << std::endl;
}
//d
void test_d(){
  Editor editor("abc");
  Runner runner(&editor,LEXICON_DIR);
  std::string cmd_line = "d 1\n";
  std::string result = runner.run(cmd_line);
  assert(result==std::string("bc"));
  std::cout << "d test success" << std::endl;
}
//l
void test_l(){
  Editor editor("abc");
  Runner runner(&editor,LEXICON_DIR);
  runner.run("d 1\n");
  std::string cmd_line = "l 1\n";
  std::string result = runner.run(cmd_line);
  assert(result==std::string("1 d 1"));
  std::cout << "l test success" << std::endl;
}
//u
void test_u(){
  Editor editor("abc");
  Runner runner(&editor,LEXICON_DIR);
  runner.run("d 1\n");
  std::string cmd_line = "u\n";
  runner.run(cmd_line);
  std::string result = runner.run("s");
  assert(result==std::string("abc"));
  std::cout << "u test success" << std::endl;
}
//r
void test_r(){
  Editor editor("abc");
  Runner runner(&editor,LEXICON_DIR);
  runner.run("d 1\n");
  std::string cmd_line = "u\n";
  runner.run(cmd_line);
  runner.run("r");
  std::string result = runner.run("s");
  assert(result==std::string("bc"));
  std::cout << "r test success" << std::endl;
}
//m
void test_m(){
  Editor editor("aaabc");
  Runner runner(&editor,LEXICON_DIR);
  runner.run("d 1\n");
  runner.run("d 1");
  runner.run("m 2 m0");
  std::string result = runner.run("$m0");
  assert(result==std::string("c"));
  std::cout << "m test success" << std::endl;
}
//spell spell-a spell-m content lang
void test_spell(){
  Editor editor("abc");
  Runner runner(&editor,LEXICON_DIR);
  std::string result = runner.run("spell");
  assert(result==std::string(""));
  runner.run("lang fra");
  result = runner.run("spell");
  assert(result==std::string("abc"));
  runner.run("a \"<a>\"");
  runner.run("lang eng");
  result = runner.run("spell");
  assert(result==std::string("<a>abc"));
  runner.run("content xml");
  result = runner.run("spell");
  assert(result==std::string(""));
  std::cout << "spell test success" << std::endl;
}
void test_spellam(){
  Editor editor("abc");
  Runner runner(&editor,LEXICON_DIR);
  runner.run("d 100");
  runner.run("a \"cde\"");
  runner.run("lang eng");
  runner.run("content txt");
  std::string result = runner.run("spell-a");
  assert(result==std::string("*[cde]"));
  result = runner.run("s");
  assert(result==std::string("cde"));
  std::cout << "spell-a test success" << std::endl;
  result = runner.run("spell-m");
  assert(result==std::string(""));
  result = runner.run("s");
  assert(result==std::string(""));
  std::cout << "spell-m test success" << std::endl;
}
std::vector<void (*)()>tests;
void init_tests(){
  tests.push_back(test_s);
  tests.push_back(test_A);
  tests.push_back(test_a);
  tests.push_back(test_D);
  tests.push_back(test_d);
  tests.push_back(test_l);
  tests.push_back(test_u);
  tests.push_back(test_r);
  tests.push_back(test_m);
  tests.push_back(test_spell);
  tests.push_back(test_spellam);
}
int main(int argc, char *argv[]){
  init_tests();
  for(auto test:tests)
    test();
  std::cout << "all the tests success" << std::endl;
  return 0;
}
